#include <config.h>
#include "nemo-history-menu-item.h"

enum
{
    CLOSE,
    LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = {0};

typedef struct
{
    GtkWidget *close_image;
    GtkWidget *clear_image;
    GtkWidget *hbox;
    GtkWidget *label;

    gboolean pressed_close_image;
    gulong close_button_clicked_handler;
    gboolean clear_all;
    gboolean pressed_clear_all;
} NemoHistoryMenuItemPrivate;


struct _NemoHistoryMenuItem
{
    GtkMenuItem parent_object;

    NemoHistoryMenuItemPrivate *priv;
};

G_DEFINE_TYPE_WITH_PRIVATE (NemoHistoryMenuItem, nemo_history_menu_item, GTK_TYPE_MENU_ITEM)

static gboolean
widget_contains_event (GtkWidget *widget, 
                       GdkEventButton *event)
{
    if (gtk_widget_get_window (widget) == NULL)
        return FALSE;

    GtkAllocation allocation;

    gtk_widget_get_allocation (widget, &allocation);

    GdkWindow *window = gtk_widget_get_window (widget);

    int xwin, ywin;

    gdk_window_get_origin (window, &xwin, &ywin);

    int xmin = allocation.x;
    int xmax = allocation.x + allocation.width;
    int ymin = allocation.y;
    int ymax = allocation.y + allocation.height; 
    int x = event->x_root - xwin;
    int y = event->y_root - ywin;

    return x >= xmin && x <= xmax && y >= ymin && y <= ymax;
}

static gboolean
nemo_history_menu_item_button_press (GtkWidget *widget, 
                                     GdkEventButton *event)
{
    NemoHistoryMenuItem *item;

    item = NEMO_HISTORY_MENU_ITEM (widget);

    if (item->priv->clear_all) {
        if (event->button == GDK_BUTTON_PRIMARY) {
            item->priv->pressed_clear_all = TRUE;
        }
    } else {
        if (event->button == GDK_BUTTON_PRIMARY && widget_contains_event (item->priv->label, event)) {
            gtk_widget_event (item->priv->label, (GdkEvent *) event);
        } else if (widget_contains_event (item->priv->close_image, event)) {
            item->priv->pressed_close_image = TRUE;
        }
    }

    return TRUE;
}

static gboolean
nemo_history_menu_item_button_release (GtkWidget *widget, 
                                       GdkEventButton *event)
{
    NemoHistoryMenuItem *item;

    item = NEMO_HISTORY_MENU_ITEM (widget);

    if (item->priv->clear_all) {
        if (event->button == GDK_BUTTON_PRIMARY && item->priv->pressed_clear_all) {
            g_signal_emit_by_name (item, "activate", NULL);
            item->priv->pressed_clear_all = FALSE;
        }
    } else {
        if (widget_contains_event (item->priv->close_image, event)) {
            if (item->priv->pressed_close_image) {
                g_signal_emit (item, signals[CLOSE], 0);
        }
        } else if (event->button == GDK_BUTTON_PRIMARY && widget_contains_event (item->priv->label, event)) {
            g_signal_emit_by_name (item, "activate", NULL);
            item->priv->pressed_close_image = FALSE;
        }
    }

    return TRUE;
}

static void
nemo_history_menu_item_finalize (GObject *object)
{
    G_OBJECT_CLASS(nemo_history_menu_item_parent_class)->finalize (object);
}

static void
nemo_history_menu_item_dispose (GObject *object)
{
    G_OBJECT_CLASS(nemo_history_menu_item_parent_class)->dispose (object);
}

static void
nemo_history_menu_item_class_init (NemoHistoryMenuItemClass *class)
{
    GObjectClass *gobject_class;
    GtkWidgetClass *widget_class;
    GtkMenuItemClass *menu_item_class;

    gobject_class = G_OBJECT_CLASS (class);
    gobject_class->dispose = nemo_history_menu_item_dispose;
    gobject_class->finalize = nemo_history_menu_item_finalize;

    widget_class = GTK_WIDGET_CLASS (class);
    widget_class->button_press_event = nemo_history_menu_item_button_press;
    widget_class->button_release_event = nemo_history_menu_item_button_release;

    menu_item_class = GTK_MENU_ITEM_CLASS (class);
    menu_item_class->hide_on_activate = FALSE;

    signals[CLOSE] = g_signal_new ("close", 
                                    G_TYPE_FROM_CLASS (class), 
                                    G_SIGNAL_RUN_LAST, 
                                    0, 
                                    NULL, NULL, NULL, 
                                    G_TYPE_NONE, 0);
}

static void
nemo_history_menu_item_init (NemoHistoryMenuItem *item)
{
    NemoHistoryMenuItemPrivate *priv;
    
    item->priv = G_TYPE_INSTANCE_GET_PRIVATE (item,
                                              NEMO_TYPE_HISTORY_MENU_ITEM,
                                              NemoHistoryMenuItemPrivate);

    priv = item->priv;

    priv->pressed_close_image = FALSE;
    priv->pressed_clear_all = FALSE;
    priv->clear_all = FALSE;

    priv->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);

    priv->clear_image = gtk_image_new_from_icon_name ("sidebar-trash-symbolic", GTK_ICON_SIZE_MENU);
    gtk_box_pack_start (GTK_BOX (priv->hbox), priv->clear_image, FALSE, FALSE, 0);

    priv->label = gtk_label_new (NULL);
    gtk_widget_set_halign (priv->label, GTK_ALIGN_FILL);
    gtk_label_set_single_line_mode (GTK_LABEL (priv->label), TRUE);
    //文字左对齐
    gtk_label_set_xalign (GTK_LABEL (priv->label), 0.0);
    gtk_box_pack_start (GTK_BOX (priv->hbox), priv->label, TRUE, TRUE, 0);

    priv->close_image = gtk_image_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_MENU);
    gtk_box_pack_end (GTK_BOX (priv->hbox), priv->close_image, FALSE, FALSE, 0);

    gtk_container_add (GTK_CONTAINER (item), priv->hbox);

    gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (item)), 
                                 "search-history-item");
    gtk_style_context_add_class (gtk_widget_get_style_context (priv->hbox), "search-history-item-hbox");

    gtk_widget_show_all (GTK_WIDGET (item));
}

void
nemo_history_menu_item_set_text (NemoHistoryMenuItem *item, 
                                 const gchar *text)
{
    gtk_label_set_text (GTK_LABEL (item->priv->label), text);
}

const gchar *
nemo_history_menu_item_get_text (NemoHistoryMenuItem *item)
{
    return gtk_label_get_text (GTK_LABEL (item->priv->label));
}

GtkWidget *
nemo_history_menu_item_new (const gchar *history, 
                            gboolean clear_all)
{
    NemoHistoryMenuItem *item;

    item = g_object_new (NEMO_TYPE_HISTORY_MENU_ITEM, NULL);

    if (history && *history) {
        nemo_history_menu_item_set_text (item, history);
    }

    item->priv->clear_all = clear_all;
    if (clear_all) {
        gtk_widget_hide (item->priv->close_image);

        gtk_style_context_add_class (gtk_widget_get_style_context (item->priv->label), 
                                     "search-history-clear-all-label");
    } else {
        gtk_widget_hide (item->priv->clear_image);

        gtk_style_context_add_class (gtk_widget_get_style_context (item->priv->label), "search-history-label");
    }

    return GTK_WIDGET (item);
}

gboolean
nemo_history_menu_item_is_clear_all (NemoHistoryMenuItem *item)
{
    return item->priv->clear_all;
}